/*
 * Copyright (C) 2010 mAPPn.Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mol.market.ui;

import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.support.v4.app.LoaderManager;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.Window;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.*;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.TabHost.OnTabChangeListener;
import android.widget.TabHost.TabSpec;
import android.widget.TextView.OnEditorActionListener;
import com.mol.market.Constants;
import com.mol.market.R;
import com.mol.market.Session;
import com.mol.market.common.network.ApiAsyncTask.ApiRequestListener;
import com.mol.market.common.network.ApiAsyncTaskLoader;
import com.mol.market.common.network.ApiRequest;
import com.mol.market.common.network.ApiResponse;
import com.mol.market.common.network.MarketAPI;
import com.mol.market.common.util.DBUtils;
import com.mol.market.common.util.DBUtils.DbOperationResultListener;
import com.mol.market.common.util.ThemeManager;
import com.mol.market.common.util.TopBar;
import com.mol.market.common.util.Utils;
import com.mol.market.common.widget.BaseTabActivity;
import com.mol.market.common.widget.InstantAutoComplete;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * this view is displaying for search tab in home
 * 
 * @author cong.li
 * @date 2011-5-9
 * @since Version 0.7.0
 */

public class SearchActivity extends BaseTabActivity implements OnClickListener,
    OnFocusChangeListener, OnEditorActionListener, ApiRequestListener,
    LoaderManager.LoaderCallbacks<ApiResponse> {

    private FrameLayout mKeywordsLayout;
    
    // Tab id
    private static final String TAB_PRODUCT_ID = "product";
    private static final String TAB_BBS_ID = "bbs";

    private TabHost mTabHost;
    private ImageButton searchBtn;
    private InstantAutoComplete mAutoCompleteTextView;
    private AutoCompleteAdapter mSearchHistoryAdapter;
    private ArrayList<String> mHistory;
    private ListView mListView;
    private SimpleAdapter mAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if(android.os.Build.VERSION.SDK_INT <= 11){
            this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        }

        setContentView(R.layout.activity_search_layout);

        if (!mSession.mIsKeyboardAvailable) {
            // 当用户没有硬键盘时，强制使用竖屏幕
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
        initTopBar();
        initView();
        initData();
    }
    
    private void initTopBar() {
        TopBar.createTopBar(mSession, this, new View[] { findViewById(R.id.top_bar_input),
                findViewById(R.id.top_bar_search) }, new int[] { View.VISIBLE, View.VISIBLE }, "");
        findViewById(R.id.top_bar_search).setOnClickListener(this);
    }

    private void initData() {
        DBUtils.querySearchHistory(getApplicationContext(),
                new DbOperationResultListener<ArrayList<String>>() {
                    @Override
                    protected void onQueryResult(ArrayList<String> result) {
                        if (mHistory == null) {
                            mHistory = result;
                        } else {
                            mHistory.addAll(result);
                        }
                        mSearchHistoryAdapter = new AutoCompleteAdapter(getApplicationContext(),
                                R.layout.activity_search_autotext_list);
                        mAutoCompleteTextView.setAdapter(mSearchHistoryAdapter);
                        mAutoCompleteTextView.setThreshold(0);
                        MarketAPI.getSearchKeywords(getApplicationContext(), SearchActivity.this);
                    }
                });
    }

    private void initView() {

        searchBtn = (ImageButton) this.findViewById(R.id.top_bar_search);
        searchBtn.setOnClickListener(this);
        mAutoCompleteTextView = (InstantAutoComplete) findViewById(R.id.top_bar_input);
        mAutoCompleteTextView.setOnFocusChangeListener(this);
        mAutoCompleteTextView.setOnEditorActionListener(this);
        mAutoCompleteTextView.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> paramAdapterView, View paramView, int paramInt,
                    long paramLong) {
                doSearch();
            }
        });
        mAutoCompleteTextView.addTextChangedListener(new TextWatcher() {
            
            @Override
            public void onTextChanged(CharSequence paramCharSequence, int paramInt1, int paramInt2,
                    int paramInt3) {
                if (mSearchHistoryAdapter != null) {
                    MarketAPI.getSearchRecommend(getApplicationContext(), SearchActivity.this,
                            paramCharSequence.toString());
                }
            }
            
            @Override
            public void beforeTextChanged(CharSequence paramCharSequence, int paramInt1, int paramInt2,
                    int paramInt3) {
            }
            
            @Override
            public void afterTextChanged(Editable paramEditable) {
            }
        });

        mKeywordsLayout = (FrameLayout) findViewById(R.id.keywrods_list);
        mListView = (ListView) findViewById(android.R.id.list);

        initTabView();
    }

    private void initSkin() {

        View tabBg = findViewById(R.id.tab_frame_layout);
        tabBg.setBackgroundResource(ThemeManager.getResource(mSession, ThemeManager.KEY_TAB_BG));
        for (int i = 0; i < 2; i++) {
            TextView v = (TextView) mTabHost.getTabWidget().getChildTabViewAt(i);

            if (i == 0) {
                Utils.createTabView(getApplicationContext(), mSession,
                        getString(R.string.tab_product), -1, v);
            } else if (i == 1) {
                Utils.createTabView(getApplicationContext(), mSession,
                        getString(R.string.tab_bbs), 1, v);
            }
        }
    }
    
    private void initTabView() {

        mTabHost = (TabHost) this.findViewById(android.R.id.tabhost);
        mTabHost.setup();
        mTabHost.getTabWidget().setPadding(mSession.mTabMargin72, 0, mSession.mTabMargin72, 0);
        FrameLayout fl = (FrameLayout) mTabHost.findViewById(R.id.tab_frame_layout);
        fl.setBackgroundResource(ThemeManager.getResource(mSession, ThemeManager.KEY_TAB_BG));
        
        Intent marketIntent = new Intent(getApplicationContext(), SearchResultActivity.class);
        marketIntent.putExtra(Constants.EXTRA_SEARCH_TYPE, Constants.SEARCH_TYPE_MARKET);
        TabSpec tab1 = mTabHost
                .newTabSpec(TAB_PRODUCT_ID)
                .setIndicator(
                        Utils.createTabView(getApplicationContext(), mSession,
                                getString(R.string.tab_product), -1, null))
                .setContent(marketIntent);
        mTabHost.addTab(tab1);

        Intent bbsIntent = new Intent(getApplicationContext(), SearchResultActivity.class);
        bbsIntent.putExtra(Constants.EXTRA_SEARCH_TYPE, Constants.SEARCH_TYPE_BBS);
        TabSpec tab2 = mTabHost
                .newTabSpec(TAB_BBS_ID)
                .setIndicator(
                        Utils.createTabView(getApplicationContext(), mSession,
                                getString(R.string.tab_bbs), 1, null)).setContent(bbsIntent);
        mTabHost.addTab(tab2);

        mTabHost.setOnTabChangedListener(new OnTabChangeListener() {

            @Override
            public void onTabChanged(String tabId) {

                if (TAB_BBS_ID.equals(tabId)) {
                    Utils.trackEvent(getApplicationContext(), Constants.GROUP_6,
                            Constants.CLICK_SEARCH_BBS);
                }
                doSearch();
            }
        });
    }

    private void showTabView() {
        resetCurrentActivity();
        mTabHost.setVisibility(View.VISIBLE);
        mKeywordsLayout.setVisibility(View.GONE);
    }

    /*
     * 初始化搜索关键词列表
     */
    private void initSearchKeywords(ArrayList<HashMap<String, Object>> keywords) {
        
        mAdapter = new SimpleAdapter(getApplicationContext(), 
                keywords,
                R.layout.search_keywords_rank_item, 
                new String[] { 
                    Constants.KEY_RANK,
                    Constants.KEY_TEXT, 
                    Constants.KEY_UP_DOWN, 
                    Constants.KEY_HAS_CHANGE}, 
                new int[] {
                    R.id.tv_rank,
                    R.id.tv_keywords, 
                    R.id.tv_change_num, 
                    R.id.tv_change_indicator});
        View v = LayoutInflater.from(getApplicationContext()).inflate(
                R.layout.activity_install_nessary_list_separator, null, false);
        TextView title = (TextView) v.findViewById(R.id.tv_name);
        title.setText(R.string.keywords_rank);
        mListView.addHeaderView(v);
        mListView.setAdapter(mAdapter);
        mListView.setOnItemClickListener(new OnItemClickListener() {
            @SuppressWarnings("unchecked")
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
                
                if (arg2 <= 0) {
                    return;
                }
                HashMap<String, Object> item = 
                    (HashMap<String, Object>) mAdapter.getItem(arg2 - 1);
                String keyword = (String)item.get(Constants.KEY_TEXT);
                mAutoCompleteTextView.setText(keyword);
                doSearch();
                // 点击关键词
                Utils.trackEvent(getApplicationContext(), Constants.GROUP_6,
                        Constants.CLICK_SEARCH_KEYWORDS);
            }
            
        });
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()) {

        case R.id.top_bar_search:
            // 点击搜索按钮
            Utils.trackEvent(getApplicationContext(), Constants.GROUP_6, Constants.CLICK_SEARCH);
            doSearch();
            break;
        }
    }
    
    @Override
    public boolean onSearchRequested() {
        doSearch();
        return true;
    }

    private void doSearch() {

        mAutoCompleteTextView.clearFocus();
        String content = mAutoCompleteTextView.getText().toString().trim();

        if (TextUtils.isEmpty(content)) {
            resetCurrentActivity();
            return;
        }

        if (!mTabHost.isShown()) {
            mTabHost.setVisibility(View.VISIBLE);
            mKeywordsLayout.setVisibility(View.GONE);
            // 开始搜索
            mTabHost.setCurrentTabByTag(TAB_PRODUCT_ID);
        }

        storeToAdapter(content);

        toogleInputMethod(false);

        SearchResultActivity resultActivity = (SearchResultActivity) getCurrentActivity();
        resultActivity.setSearchKeyword(content);
        resultActivity.lazyload();
    }

    private void resetCurrentActivity() {
        SearchResultActivity resultActivity = (SearchResultActivity) getCurrentActivity();
        resultActivity.resetSearchResult();
    }

    /**
     * 将搜索内容添加到数据源adapter
     */
    private void storeToAdapter(String content) {

        if (mSearchHistoryAdapter == null) {
            return;
        }
        
        if (mHistory == null) {
            mHistory = new ArrayList<String>();
        }
        
        if (!mHistory.contains(content)) {
            mHistory.add(content);
            mSearchHistoryAdapter.add(content);
            mSearchHistoryAdapter.notifyDataSetChanged();
            DBUtils.addSearchItem(getApplicationContext(), content);
        }

    }

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        switch (v.getId()) {
        case R.id.top_bar_input:
            toogleInputMethod(hasFocus);
            break;

        default:
            break;
        }
    }

    public void setKeyword(String text) {
        if (mAutoCompleteTextView != null) {
            mAutoCompleteTextView.setText(text);
        }
    }


    public String getKeyword() {
        if (mAutoCompleteTextView != null) {
            return mAutoCompleteTextView.getText().toString();
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    @Override
    public void onSuccess(int method, Object obj) {
        switch (method) {

            case MarketAPI.ACTION_GET_SEARCH_KEYWORDS:
                initSearchKeywords((ArrayList<HashMap<String, Object>>) obj);
                break;

            case MarketAPI.ACTION_GET_SEARCH_RECOMMEND:

                mSearchHistoryAdapter.clear();
                ArrayList<String> keywords = (ArrayList<String>) obj;
                for (String keyword : keywords) {
                    mSearchHistoryAdapter.add(keyword);
                }
                mSearchHistoryAdapter.notifyDataSetChanged();
                break;
        }
    }

    @Override
    public void onError(int method, int statusCode) {
        Utils.D("fetch keywords fail because of status " + statusCode);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if (KeyEvent.KEYCODE_BACK == keyCode && mTabHost != null && mTabHost.isShown()) {
            mAutoCompleteTextView.setText("");
            mTabHost.setCurrentTabByTag(TAB_PRODUCT_ID);
            mTabHost.requestFocus();
            mTabHost.setVisibility(View.GONE);
            resetCurrentActivity();
            mKeywordsLayout.setVisibility(View.VISIBLE);
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    // toogle input method status
    private void toogleInputMethod(boolean flag) {
        InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
        if (flag) {
            imm.showSoftInputFromInputMethod(mAutoCompleteTextView.getWindowToken(), 0);
            showTabView();
        } else {
            imm.hideSoftInputFromWindow(mAutoCompleteTextView.getWindowToken(), 0);
        }
    }

    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {

        if (actionId == EditorInfo.IME_ACTION_DONE
                || actionId == EditorInfo.IME_ACTION_NEXT) {
            doSearch();
            Utils.trackEvent(getApplicationContext(), Constants.GROUP_6, Constants.CLICK_SEARCH);
            return true;
        }
        return false;
    }


    @Override
    public android.support.v4.content.Loader<ApiResponse> onCreateLoader(int i, Bundle bundle) {

        switch (i) {
            case MarketAPI.ACTION_GET_SEARCH_RECOMMEND:

                ApiRequest request = MarketAPI.getSearchRecommend(getApplicationContext(),
                    (String) bundle.get("keyword"));
                return new ApiAsyncTaskLoader(getApplicationContext(), request);
        }
        return null;
    }


    @Override
    public void onLoadFinished(android.support.v4.content.Loader<ApiResponse> apiResponseLoader, ApiResponse apiResponse) {
        Utils.D("api response >" + apiResponse.result);
    }

    @Override
    public void onLoaderReset(android.support.v4.content.Loader<ApiResponse> apiResponseLoader) {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    /**
     * 搜索推荐Adapter
     */
    private class AutoCompleteAdapter extends ArrayAdapter<String> {


        private CustomFilter mCustomFilter = null;


        @Override
        public Filter getFilter() {

            if (mCustomFilter == null)
                mCustomFilter = new CustomFilter();
            return mCustomFilter;
        }

        public AutoCompleteAdapter(Context context, int textViewResourceId) {
            super(context, textViewResourceId);
        }
        
        private class CustomFilter extends Filter {


            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults fr = null;
                if (constraint != null) {
                    List<String> list = mHistory;

                    if (list != null) {
                        fr = new FilterResults();
                        fr.values = list;
                        fr.count = list.size();
                    }
                }
                return fr;
            }

            @Override
            protected void publishResults(CharSequence paramCharSequence, FilterResults results) {
                AutoCompleteAdapter.this.clear();
                if (results != null) {
                    if (results.values != null) {
                        @SuppressWarnings("unchecked")
                        List<String> items = (List<String>) results.values;

                        for (String listItem : items) {
                            AutoCompleteAdapter.this.add(listItem);
                        }

                        if (items.size() > 0) {
                            AutoCompleteAdapter.this.notifyDataSetChanged();
                            return;
                        }
                    }
                }
                AutoCompleteAdapter.this.notifyDataSetInvalidated();
            }
        }
    }

}